from starlette.authentication import requires
from fastapi import APIRouter, Request, Depends
from fastapi.encoders import jsonable_encoder

from myPsycho.db_config.odmantic_config import create_db_engine
from myPsycho.repository.scale_repo import ScaleRepository
from myPsycho.scoring.scoring_scales import scoring_the_scale

from pydantic import BaseModel
from typing import Dict, Any, Optional
import asyncio

from myPsychology.utility.enums import Gender, Profession


class AnswerReq(BaseModel):
    abbr: str
    answers: Dict[str, Any]
    sub_answers: Optional[Dict[str, Any]] = None
    age: Optional[int] = None
    gender: Optional[Gender] = None
    profession: Optional[Profession] = None


router = APIRouter()


@router.get("/scales/name")
@requires("authenticated")
async def get_scale_by_name(request: Request, name: str,
                            engine=Depends(create_db_engine)):
    repo: ScaleRepository = ScaleRepository(engine)
    return await repo.get_scale_by_name(name)


@router.get("/scales/abbr")
@requires("authenticated")
async def get_scale_by_abbr(request: Request, abbr: str,
                            engine=Depends(create_db_engine)):
    repo: ScaleRepository = ScaleRepository(engine)
    return await repo.get_scale_by_abbr(abbr)


@router.get("/scales/all")
@requires("authenticated")
async def get_all_scales(request: Request,
                         engine=Depends(create_db_engine)):
    repo: ScaleRepository = ScaleRepository(engine)
    return await repo.get_all_scales()


@router.post("/scales/score")
@requires("authenticated")
async def scale_score_by_abbr(request: Request, answers: AnswerReq,
                              engine=Depends(create_db_engine)):
    repo: ScaleRepository = ScaleRepository(engine)

    the_answers = answers.model_dump(exclude_unset=True)

    the_scale = await repo.get_scale_by_abbr(the_answers['abbr'])

    scores = await asyncio.to_thread(scoring_the_scale, the_scale, the_answers)
    return jsonable_encoder(scores)
